import 'dart:core';
import 'dart:math';
import 'dart:ui' as ui;

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

///https://juejin.cn/book/6844733827265331214/section/6844733827307274247
///path 绘制学习

class DrawPathLearningWidget extends StatefulWidget {
  @override
  _DrawPathLearningWidgetState createState() => _DrawPathLearningWidgetState();
}

class _DrawPathLearningWidgetState extends State<DrawPathLearningWidget> {
  ui.Image? _image;

  @override
  void initState() {
    super.initState();
    _loadImage();
  }

  void _loadImage() async {
    _image = await loadImageFromAssets('images/ic_bind_card_gray.png');
    setState(() {});
  }

  ///通过 decodeImageFromList 方法
  ///可以将一个字节流转换为ui.Image 对象。
  ///将 images 的文件读取为字节流可以使用 rootBundle.load 方法。
  Future<ui.Image>? loadImageFromAssets(String path) async {
    ByteData data = await rootBundle.load(path);
    return decodeImageFromList(data.buffer.asUint8List());
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      child: Center(
          child: Container(
        child: Listener(
          onPointerDown: (details) {
            // var offset =
            //     Offset(details.localPosition.dx, details.localPosition.dy);
            // quadtree.insert(quadtree, offset);
            // print("点击：${offset.toString()}");
            // setState(() {});
          },
          child: Container(
            width: double.infinity,
            height: double.infinity,
            color: Color(0xffffffff),
            child: RepaintBoundary(
              //隔离重绘控件，singlescrollview 滑动发生重绘，导致画笔paint响应
              child: CustomPaint(
                painter: _PathPainter(_image),
              ),
            ),
          ),
        ),
      )),
    );
  }

  @override
  void dispose() {
    super.dispose();
  }
}

class _PathPainter extends CustomPainter {
  double radius = 20;
  final ui.Image? image;

  _PathPainter(this.image);

  @override
  void paint(Canvas canvas, Size size) {
    Paint _painter = Paint()
      ..color = Color(0xFF00FDF4)
      ..style = PaintingStyle.fill
      ..isAntiAlias = true;

    Paint _painterLine = Paint()
      ..color = Color(0xFFF50000)
      ..style = PaintingStyle.stroke
      ..isAntiAlias = true;

    Paint _painterTowLine = Paint()
      ..color = Color(0xFF000000)
      ..style = PaintingStyle.stroke
      ..isAntiAlias = true;

    canvas.translate(100, 100);
    //画网格
    _drawGrid(canvas, Size(100, 100));
    //画圆
    _drawCircle(canvas);
    //画圆旁边的点
    _drawDot(canvas);

    //移动
    canvas.translate(100, 100);
    _drawImage(canvas);

    //移动
    canvas.translate(100, 100);
    _drawTextPaintShowSize(canvas);

    //移动
    canvas.translate(100, 100);
    _drawArcPaint(canvas);

    //移动
    canvas.translate(-300, 100);
    drawLine(canvas);
  }

  void _drawCircle(Canvas canvas) {
    Paint paint = Paint()
      ..color = Color(0xFF00A6FF)
      ..style = PaintingStyle.fill
      ..isAntiAlias = true;
    canvas.drawCircle(Offset(0, 0), 50, paint);
    canvas.drawLine(
        Offset(20, 20),
        Offset(50, 50),
        paint
          ..color = Colors.red
          ..strokeWidth = 5
          ..strokeCap = StrokeCap.round
          ..style = PaintingStyle.stroke);
  }

  void _drawDot(Canvas canvas) {
    final int count = 12;
    Paint paint = Paint()
      ..color = Colors.orangeAccent
      ..style = PaintingStyle.stroke;
    canvas.save();
    for (int i = 0; i < count; i++) {
      var step = 2 * pi / count;
      canvas.drawLine(Offset(80, 0), Offset(100, 0), paint);
      canvas.rotate(step);
    }
    canvas.restore();
  }

  //4分之一网格
  void _drawBottomRight(Canvas canvas, Size size) {
    double step = 10;
    canvas.save();
    Paint _gridPint = Paint()
      ..color = Color(0xFF000000)
      ..style = PaintingStyle.fill
      ..isAntiAlias = true;
    for (int i = 0; i < size.height / 2 / step; i++) {
      canvas.drawLine(Offset(0, 0), Offset(size.width / 2, 0), _gridPint);
      canvas.translate(0, step);
    }
    canvas.restore();

    canvas.save();
    for (int i = 0; i < size.width / 2 / step; i++) {
      canvas.drawLine(Offset(0, 0), Offset(0, size.height / 2), _gridPint);
      canvas.translate(step, 0);
    }
    canvas.restore();
  }

  //网格
  void _drawGrid(Canvas canvas, Size size) {
    _drawBottomRight(canvas, size);
    canvas.save();
    canvas.scale(1, -1); //沿x轴镜像
    _drawBottomRight(canvas, size);
    canvas.restore();

    canvas.save();
    canvas.scale(-1, 1); //沿y轴镜像
    _drawBottomRight(canvas, size);
    canvas.restore();
    //
    canvas.save();
    canvas.scale(-1, -1); //沿原点镜像
    _drawBottomRight(canvas, size);
    canvas.restore();
  }

  void _drawImage(Canvas canvas) async {
    canvas.save();

    Paint _paint = Paint()
      ..color = Color(0xFF0052FF)
      ..style = PaintingStyle.fill
      ..isAntiAlias = true;
    if (image != null) {
      // canvas.drawImageNine(
      //     image!,
      //     Rect.fromCenter(center: Offset(image!.width/2, image!.height-6.0),
      //         width: image!.width-20.0, height: 2.0),
      //     Rect.fromCenter(center: Offset(0, 0,), width:300, height: 120),
      //     _paint);

      // canvas.drawImage(
      //     image!, Offset(-image!.width/2, -image!.height/2), _paint);
      // canvas.restore();
      //
      // canvas.save();
      canvas.drawImageRect(
          image!,
          Rect.fromCenter(
              center: Offset(image!.width / 2, image!.height / 2 - 60),
              width: 60,
              height: 60),
          Rect.fromLTRB(0, 0, 100, 100).translate(0, 0),
          _paint);
      // canvas.restore();
    }
  }

  void _drawTextPaintShowSize(Canvas canvas) {
    Paint _paint = Paint()
      ..color = Color(0xFF0052FF)
      ..style = PaintingStyle.stroke
      ..isAntiAlias = true;

    TextPainter textPainter = TextPainter(
        text: TextSpan(
            text: 'Flutter Unit',
            style: TextStyle(fontSize: 40, color: Colors.black)),
        textAlign: TextAlign.center,
        textDirection: TextDirection.ltr);
    textPainter.layout(); // 进行布局
    Size size = textPainter.size; // 尺寸必须在布局后获取
    textPainter.paint(canvas, Offset(-size.width / 2, -size.height / 2));

    canvas.drawRect(
        Rect.fromLTRB(0, 0, size.width, size.height)
            .translate(-size.width / 2, -size.height / 2),
        _paint);
  }

  ///画圆弧
  void _drawArcPaint(Canvas canvas) {
    Path path = Path();
    Paint paint = Paint()
      ..color = Colors.purpleAccent
      ..strokeWidth = 2
      ..style = PaintingStyle.stroke;

    // 绘制左侧
    var rect = Rect.fromCenter(center: Offset(0, 0), width: 160, height: 100);
    path.lineTo(30, 30);
    path..arcTo(rect, 0, pi * 1.5, true);
    canvas.drawPath(path, paint);

    path.reset();
    canvas.translate(200, 0);
    // 绘制右侧
    path.lineTo(30, 30);
    path..arcTo(rect, 0, pi * 1.5, false);
    canvas.drawPath(path, paint);

    ///画圆弧到某个点 ---arcToPoint
    canvas.translate(300, 0);
    paint.color = Color(0xFF0062F3);
    //绘制中间
    path
      ..arcToPoint(
        Offset(40, 40),
        radius: Radius.circular(60),
        largeArc: false,
      )
      ..close();
    canvas.drawPath(path, paint);

    path.reset();
    canvas.translate(-150, 0);
    //绘制左侧
    path.lineTo(80, -40);
    path
      ..arcToPoint(Offset(40, 40),
          radius: Radius.circular(60), largeArc: true, clockwise: false)
      ..close();
    canvas.drawPath(path, paint);

    path.reset();
    canvas.translate(150 + 150.0, 0);
    //绘制右侧
    path.lineTo(80, -40);
    path
      ..arcToPoint(
        Offset(40, 40),
        radius: Radius.circular(60),
        largeArc: true,
      )
      ..close();
    canvas.drawPath(path, paint);
  }

  void drawLine(Canvas canvas) {
    Offset start = Offset(100, 0);
    Offset  end = Offset(200, 100);

    final Paint pointPaint = Paint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1;

    canvas.drawLine(start, end, pointPaint);

    canvas.drawCircle(start, 4, pointPaint..style = PaintingStyle.stroke);
    canvas.drawCircle(end, 2, pointPaint..style = PaintingStyle.fill);

    double  rad =(end - start).direction;
    double  length = (end - start).distance;

    rad = rad < 0 ? 2 * pi + rad : rad;
    double rotate = pi/180*90;
    double detaRotate = 0;
     detaRotate = rotate - detaRotate;
    end = Offset(
      length * cos(rad + detaRotate),
      length * sin(rad + detaRotate),
    ) + start;

    canvas.drawLine(start, end, pointPaint);

  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}
